package com.atguigu.spring6.xmltx.service;

import com.atguigu.spring6.xmltx.dao.BookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;


@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;

    /**
     * 只读
     * @param bookId
     * @param userId
     */
    @Transactional(readOnly = true)
    @Override
    public void buyBook4(Integer bookId, Integer userId) {
        //TODO 模拟超时效果
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //根据图书id查询图书价格
        Integer price= bookDao.getBookPriceByBookId(bookId);
        //更新图书表库存量 -1
        bookDao.updateStock(bookId);
        //更新用户表用户余额 -图书价格
        bookDao.updateUserBlance(userId,price);
        System.out.println(1/0);
    }
    /**
     *
     * 超时
     * @param bookId
     * @param userId
     */
    @Transactional(timeout = 3)
    @Override
    public void buyBook1(Integer bookId, Integer userId) {
        //TODO 模拟超时效果
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //根据图书id查询图书价格
        Integer price= bookDao.getBookPriceByBookId(bookId);
        //更新图书表库存量 -1
        bookDao.updateStock(bookId);
        //更新用户表用户余额 -图书价格
        bookDao.updateUserBlance(userId,price);
        System.out.println(1/0);
    }

    /**
     * 回滚策略
     * 测试发生某类异常不会回滚事务
     * @param bookId
     * @param userId
     */
    @Transactional(noRollbackFor = ArithmeticException.class)
    @Override
    public void buyBook2(Integer bookId, Integer userId) {
        //根据图书id查询图书价格
        Integer price= bookDao.getBookPriceByBookId(bookId);
        //更新图书表库存量 -1
        bookDao.updateStock(bookId);
        //更新用户表用户余额 -图书价格
        bookDao.updateUserBlance(userId,price);
        System.out.println(1/0);
    }

    /**
     * 隔离级别
     * @param bookId
     * @param userId
     */
    @Transactional(isolation = Isolation.DEFAULT)
    @Override
    public void buyBook3(Integer bookId, Integer userId) {
        //根据图书id查询图书价格
        Integer price= bookDao.getBookPriceByBookId(bookId);
        //更新图书表库存量 -1
        bookDao.updateStock(bookId);
        //更新用户表用户余额 -图书价格
        bookDao.updateUserBlance(userId,price);
        System.out.println(1/0);
    }
    /**
     * 传播行为
     * requires:当前有事务就用当前事务
     * requires_new：不管当前线程上是否有已经开始的事务，都开启一个新的事务
     * @param bookId
     * @param userId
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void buyBook(Integer bookId, Integer userId) {
        //根据图书id查询图书价格
        Integer price= bookDao.getBookPriceByBookId(bookId);
        //更新图书表库存量 -1
        bookDao.updateStock(bookId);
        //更新用户表用户余额 -图书价格
        bookDao.updateUserBlance(userId,price);

    }
}
